middleware.cjs 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", { value: !0 });
  3. var http = require("http"), https = require("https"), debugIt = require("debug"), defaultOptionsValidator = require("./_chunks/defaultOptionsValidator-CXwrNjme.cjs"), isPlainObject = require("is-plain-object"), progressStream = require("progress-stream"), allowed = require("is-retry-allowed");
  4. function _interopDefaultCompat(e) {
  5. return e && typeof e == "object" && "default" in e ? e : { default: e };
  6. }
  7. var debugIt__default = /* @__PURE__ */ _interopDefaultCompat(debugIt), progressStream__default = /* @__PURE__ */ _interopDefaultCompat(progressStream), allowed__default = /* @__PURE__ */ _interopDefaultCompat(allowed);
  8. const isHttpsProto = /^https:/i;
  9. function agent(opts) {
  10. const httpAgent = new http.Agent(opts), httpsAgent = new https.Agent(opts), agents = { http: httpAgent, https: httpsAgent };
  11. return {
  12. finalizeOptions: (options) => {
  13. if (options.agent)
  14. return options;
  15. if (options.maxRedirects > 0)
  16. return { ...options, agents };
  17. const isHttps = isHttpsProto.test(options.href || options.protocol);
  18. return { ...options, agent: isHttps ? httpsAgent : httpAgent };
  19. }
  20. };
  21. }
  22. const leadingSlash = /^\//, trailingSlash = /\/$/;
  23. function base(baseUrl) {
  24. const baseUri = baseUrl.replace(trailingSlash, "");
  25. return {
  26. processOptions: (options) => {
  27. if (/^https?:\/\//i.test(options.url))
  28. return options;
  29. const url = [baseUri, options.url.replace(leadingSlash, "")].join("/");
  30. return Object.assign({}, options, { url });
  31. }
  32. };
  33. }
  34. const SENSITIVE_HEADERS = ["cookie", "authorization"], hasOwn = Object.prototype.hasOwnProperty, redactKeys = (source, redacted) => {
  35. const target = {};
  36. for (const key in source)
  37. hasOwn.call(source, key) && (target[key] = redacted.indexOf(key.toLowerCase()) > -1 ? "<redacted>" : source[key]);
  38. return target;
  39. };
  40. function debug(opts = {}) {
  41. const verbose = opts.verbose, namespace = opts.namespace || "get-it", defaultLogger = debugIt__default.default(namespace), log = opts.log || defaultLogger, shortCircuit = log === defaultLogger && !debugIt__default.default.enabled(namespace);
  42. let requestId = 0;
  43. return {
  44. processOptions: (options) => (options.debug = log, options.requestId = options.requestId || ++requestId, options),
  45. onRequest: (event) => {
  46. if (shortCircuit || !event)
  47. return event;
  48. const options = event.options;
  49. if (log("[%s] HTTP %s %s", options.requestId, options.method, options.url), verbose && options.body && typeof options.body == "string" && log("[%s] Request body: %s", options.requestId, options.body), verbose && options.headers) {
  50. const headers2 = opts.redactSensitiveHeaders === !1 ? options.headers : redactKeys(options.headers, SENSITIVE_HEADERS);
  51. log("[%s] Request headers: %s", options.requestId, JSON.stringify(headers2, null, 2));
  52. }
  53. return event;
  54. },
  55. onResponse: (res, context) => {
  56. if (shortCircuit || !res)
  57. return res;
  58. const reqId = context.options.requestId;
  59. return log("[%s] Response code: %s %s", reqId, res.statusCode, res.statusMessage), verbose && res.body && log("[%s] Response body: %s", reqId, stringifyBody(res)), res;
  60. },
  61. onError: (err, context) => {
  62. const reqId = context.options.requestId;
  63. return err ? (log("[%s] ERROR: %s", reqId, err.message), err) : (log("[%s] Error encountered, but handled by an earlier middleware", reqId), err);
  64. }
  65. };
  66. }
  67. function stringifyBody(res) {
  68. return (res.headers["content-type"] || "").toLowerCase().indexOf("application/json") !== -1 ? tryFormat(res.body) : res.body;
  69. }
  70. function tryFormat(body) {
  71. try {
  72. const parsed = typeof body == "string" ? JSON.parse(body) : body;
  73. return JSON.stringify(parsed, null, 2);
  74. } catch {
  75. return body;
  76. }
  77. }
  78. function headers(_headers, opts = {}) {
  79. return {
  80. processOptions: (options) => {
  81. const existing = options.headers || {};
  82. return options.headers = opts.override ? Object.assign({}, existing, _headers) : Object.assign({}, _headers, existing), options;
  83. }
  84. };
  85. }
  86. class HttpError extends Error {
  87. constructor(res, ctx) {
  88. super();
  89. const truncatedUrl = res.url.length > 400 ? `${res.url.slice(0, 399)}\u2026` : res.url;
  90. let msg = `${res.method}-request to ${truncatedUrl} resulted in `;
  91. msg += `HTTP ${res.statusCode} ${res.statusMessage}`, this.message = msg.trim(), this.response = res, this.request = ctx.options;
  92. }
  93. }
  94. function httpErrors() {
  95. return {
  96. onResponse: (res, ctx) => {
  97. if (!(res.statusCode >= 400))
  98. return res;
  99. throw new HttpError(res, ctx);
  100. }
  101. };
  102. }
  103. function injectResponse(opts = {}) {
  104. if (typeof opts.inject != "function")
  105. throw new Error("`injectResponse` middleware requires a `inject` function");
  106. return { interceptRequest: function(prevValue, event) {
  107. const response = opts.inject(event, prevValue);
  108. if (!response)
  109. return prevValue;
  110. const options = event.context.options;
  111. return {
  112. body: "",
  113. url: options.url,
  114. method: options.method,
  115. headers: {},
  116. statusCode: 200,
  117. statusMessage: "OK",
  118. ...response
  119. };
  120. } };
  121. }
  122. const isBuffer = typeof Buffer > "u" ? () => !1 : (obj) => Buffer.isBuffer(obj), serializeTypes = ["boolean", "string", "number"];
  123. function jsonRequest() {
  124. return {
  125. processOptions: (options) => {
  126. const body = options.body;
  127. return !body || !(typeof body.pipe != "function" && !isBuffer(body) && (serializeTypes.indexOf(typeof body) !== -1 || Array.isArray(body) || isPlainObject.isPlainObject(body))) ? options : Object.assign({}, options, {
  128. body: JSON.stringify(options.body),
  129. headers: Object.assign({}, options.headers, {
  130. "Content-Type": "application/json"
  131. })
  132. });
  133. }
  134. };
  135. }
  136. function jsonResponse(opts) {
  137. return {
  138. onResponse: (response) => {
  139. const contentType = response.headers["content-type"] || "", shouldDecode = opts && opts.force || contentType.indexOf("application/json") !== -1;
  140. return !response.body || !contentType || !shouldDecode ? response : Object.assign({}, response, { body: tryParse(response.body) });
  141. },
  142. processOptions: (options) => Object.assign({}, options, {
  143. headers: Object.assign({ Accept: "application/json" }, options.headers)
  144. })
  145. };
  146. function tryParse(body) {
  147. try {
  148. return JSON.parse(body);
  149. } catch (err) {
  150. throw err.message = `Failed to parsed response body as JSON: ${err.message}`, err;
  151. }
  152. }
  153. }
  154. function isBrowserOptions(options) {
  155. return typeof options == "object" && options !== null && !("protocol" in options);
  156. }
  157. function mtls(config = {}) {
  158. if (!config.ca)
  159. throw new Error('Required mtls option "ca" is missing');
  160. if (!config.cert)
  161. throw new Error('Required mtls option "cert" is missing');
  162. if (!config.key)
  163. throw new Error('Required mtls option "key" is missing');
  164. return {
  165. finalizeOptions: (options) => {
  166. if (isBrowserOptions(options))
  167. return options;
  168. const mtlsOpts = {
  169. cert: config.cert,
  170. key: config.key,
  171. ca: config.ca
  172. };
  173. return Object.assign({}, options, mtlsOpts);
  174. }
  175. };
  176. }
  177. let actualGlobal = {};
  178. typeof globalThis < "u" ? actualGlobal = globalThis : typeof window < "u" ? actualGlobal = window : typeof global < "u" ? actualGlobal = global : typeof self < "u" && (actualGlobal = self);
  179. var global$1 = actualGlobal;
  180. function observable(opts = {}) {
  181. const Observable = (
  182. // eslint-disable-next-line @typescript-eslint/no-explicit-any -- @TODO consider dropping checking for a global Observable since it's not on a standards track
  183. opts.implementation || global$1.Observable
  184. );
  185. if (!Observable)
  186. throw new Error(
  187. "`Observable` is not available in global scope, and no implementation was passed"
  188. );
  189. return {
  190. onReturn: (channels, context) => new Observable((observer) => (channels.error.subscribe((err) => observer.error(err)), channels.progress.subscribe(
  191. (event) => observer.next(Object.assign({ type: "progress" }, event))
  192. ), channels.response.subscribe((response) => {
  193. observer.next(Object.assign({ type: "response" }, response)), observer.complete();
  194. }), channels.request.publish(context), () => channels.abort.publish()))
  195. };
  196. }
  197. function normalizer(stage) {
  198. return (prog) => ({
  199. stage,
  200. percent: prog.percentage,
  201. total: prog.length,
  202. loaded: prog.transferred,
  203. lengthComputable: !(prog.length === 0 && prog.percentage === 0)
  204. });
  205. }
  206. function progress() {
  207. return {
  208. onHeaders: (response, evt) => {
  209. const _progress = progressStream__default.default({ time: 16 }), normalize = normalizer("download"), contentLength = response.headers["content-length"], length = contentLength ? Number(contentLength) : 0;
  210. return !isNaN(length) && length > 0 && _progress.setLength(length), _progress.on("progress", (prog) => evt.context.channels.progress.publish(normalize(prog))), response.pipe(_progress);
  211. },
  212. onRequest: (evt) => {
  213. if (!evt.progress)
  214. return;
  215. const normalize = normalizer("upload");
  216. evt.progress.on(
  217. "progress",
  218. (prog) => evt.context.channels.progress.publish(normalize(prog))
  219. );
  220. }
  221. };
  222. }
  223. const promise = (options = {}) => {
  224. const PromiseImplementation = options.implementation || Promise;
  225. if (!PromiseImplementation)
  226. throw new Error("`Promise` is not available in global scope, and no implementation was passed");
  227. return {
  228. onReturn: (channels, context) => new PromiseImplementation((resolve, reject) => {
  229. const cancel = context.options.cancelToken;
  230. cancel && cancel.promise.then((reason) => {
  231. channels.abort.publish(reason), reject(reason);
  232. }), channels.error.subscribe(reject), channels.response.subscribe((response) => {
  233. resolve(options.onlyBody ? response.body : response);
  234. }), setTimeout(() => {
  235. try {
  236. channels.request.publish(context);
  237. } catch (err) {
  238. reject(err);
  239. }
  240. }, 0);
  241. })
  242. };
  243. };
  244. class Cancel {
  245. constructor(message) {
  246. this.__CANCEL__ = !0, this.message = message;
  247. }
  248. toString() {
  249. return `Cancel${this.message ? `: ${this.message}` : ""}`;
  250. }
  251. }
  252. const _CancelToken = class {
  253. constructor(executor) {
  254. if (typeof executor != "function")
  255. throw new TypeError("executor must be a function.");
  256. let resolvePromise = null;
  257. this.promise = new Promise((resolve) => {
  258. resolvePromise = resolve;
  259. }), executor((message) => {
  260. this.reason || (this.reason = new Cancel(message), resolvePromise(this.reason));
  261. });
  262. }
  263. };
  264. _CancelToken.source = () => {
  265. let cancel;
  266. return {
  267. token: new _CancelToken((can) => {
  268. cancel = can;
  269. }),
  270. cancel
  271. };
  272. };
  273. let CancelToken = _CancelToken;
  274. const isCancel = (value) => !!(value && value != null && value.__CANCEL__);
  275. promise.Cancel = Cancel;
  276. promise.CancelToken = CancelToken;
  277. promise.isCancel = isCancel;
  278. function proxy(_proxy) {
  279. if (_proxy !== !1 && (!_proxy || !_proxy.host))
  280. throw new Error("Proxy middleware takes an object of host, port and auth properties");
  281. return {
  282. processOptions: (options) => Object.assign({ proxy: _proxy }, options)
  283. };
  284. }
  285. var defaultShouldRetry = (err, num, options) => options.method !== "GET" && options.method !== "HEAD" || err.response && err.response.statusCode ? !1 : allowed__default.default(err);
  286. const isStream = (stream) => stream !== null && typeof stream == "object" && typeof stream.pipe == "function";
  287. var sharedRetry = (opts) => {
  288. const maxRetries = opts.maxRetries || 5, retryDelay = opts.retryDelay || getRetryDelay, allowRetry = opts.shouldRetry;
  289. return {
  290. onError: (err, context) => {
  291. const options = context.options, max = options.maxRetries || maxRetries, shouldRetry = options.shouldRetry || allowRetry, attemptNumber = options.attemptNumber || 0;
  292. if (isStream(options.body) || !shouldRetry(err, attemptNumber, options) || attemptNumber >= max)
  293. return err;
  294. const newContext = Object.assign({}, context, {
  295. options: Object.assign({}, options, { attemptNumber: attemptNumber + 1 })
  296. });
  297. return setTimeout(() => context.channels.request.publish(newContext), retryDelay(attemptNumber)), null;
  298. }
  299. };
  300. };
  301. function getRetryDelay(attemptNum) {
  302. return 100 * Math.pow(2, attemptNum) + Math.random() * 100;
  303. }
  304. const retry = (opts = {}) => sharedRetry({ shouldRetry: defaultShouldRetry, ...opts });
  305. retry.shouldRetry = defaultShouldRetry;
  306. function encode(data) {
  307. const query = new URLSearchParams(), nest = (name, _value) => {
  308. const value = _value instanceof Set ? Array.from(_value) : _value;
  309. if (Array.isArray(value))
  310. if (value.length)
  311. for (const index in value)
  312. nest(`${name}[${index}]`, value[index]);
  313. else
  314. query.append(`${name}[]`, "");
  315. else if (typeof value == "object" && value !== null)
  316. for (const [key, obj] of Object.entries(value))
  317. nest(`${name}[${key}]`, obj);
  318. else
  319. query.append(name, value);
  320. };
  321. for (const [key, value] of Object.entries(data))
  322. nest(key, value);
  323. return query.toString();
  324. }
  325. function urlEncoded() {
  326. return {
  327. processOptions: (options) => {
  328. const body = options.body;
  329. return !body || !(typeof body.pipe != "function" && !isBuffer(body) && isPlainObject.isPlainObject(body)) ? options : {
  330. ...options,
  331. body: encode(options.body),
  332. headers: {
  333. ...options.headers,
  334. "Content-Type": "application/x-www-form-urlencoded"
  335. }
  336. };
  337. }
  338. };
  339. }
  340. function buildKeepAlive(agent2) {
  341. return function(config = {}) {
  342. const ms = config.ms || 1e3, maxFree = config.maxFree || 256;
  343. return agent2({
  344. keepAlive: !0,
  345. keepAliveMsecs: ms,
  346. maxFreeSockets: maxFree
  347. });
  348. };
  349. }
  350. const keepAlive = buildKeepAlive(agent);
  351. exports.processOptions = defaultOptionsValidator.processOptions;
  352. exports.validateOptions = defaultOptionsValidator.validateOptions;
  353. exports.Cancel = Cancel;
  354. exports.CancelToken = CancelToken;
  355. exports.agent = agent;
  356. exports.base = base;
  357. exports.debug = debug;
  358. exports.headers = headers;
  359. exports.httpErrors = httpErrors;
  360. exports.injectResponse = injectResponse;
  361. exports.jsonRequest = jsonRequest;
  362. exports.jsonResponse = jsonResponse;
  363. exports.keepAlive = keepAlive;
  364. exports.mtls = mtls;
  365. exports.observable = observable;
  366. exports.progress = progress;
  367. exports.promise = promise;
  368. exports.proxy = proxy;
  369. exports.retry = retry;
  370. exports.urlEncoded = urlEncoded;
  371. //# sourceMappingURL=middleware.cjs.map