middleware.browser.cjs 13 KB

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