// src/fetch.ts
var ResponseError = class extends Error {
  constructor(r, body) {
    super(r.statusText);
    this.code = r.status;
    this.response = r;
    this.body = body;
  }
};
var overrideHTTPMethod = false;
function enableHTTPMethodOveride(enable) {
  overrideHTTPMethod = enable;
}
var fetch_default = (fetch) => {
  function isPlainObject(obj) {
    if (typeof obj !== "object" || obj === null)
      return false;
    let proto = obj;
    while (Object.getPrototypeOf(proto) !== null) {
      proto = Object.getPrototypeOf(proto);
    }
    return Object.getPrototypeOf(obj) === proto;
  }
  return function fetchEx2(url, initEx) {
    const { beforeRequest, customParser, ...rawInit } = { ...initEx };
    if (rawInit.headers) {
      Object.keys(rawInit.headers).forEach((key) => {
        const lowerCaseKey = key.toLowerCase();
        if (lowerCaseKey !== key) {
          rawInit.headers[lowerCaseKey] = rawInit.headers[key];
          delete rawInit.headers[key];
        }
      });
    }
    beforeRequest?.(url, rawInit);
    let { timeout = 5e3, json, text, blob, buffer, headers = {}, ...init } = rawInit;
    if (init.method) {
      const method = init.method.toUpperCase();
      if (["PUT", "PATCH", "DELETE"].includes(method) && overrideHTTPMethod) {
        headers = { ...headers, "x-http-method-override": method };
        init.method = "POST";
      }
    }
    if (isPlainObject(init.body)) {
      headers["content-type"] = "application/json;charset=UTF-8";
      init.body = JSON.stringify(init.body);
    }
    init.headers = headers;
    function defaultParser(r) {
      let method = blob ? "blob" : buffer ? "arrayBuffer" : json ? "json" : text ? "text" : void 0;
      if (method === void 0) {
        const [type] = (r.headers.get("content-type") || "").split(";");
        const [majorType, minorType] = type.split("/");
        if (majorType === "application") {
          if (minorType === "json") {
            method = "json";
          } else if (minorType === "octet-stream") {
            method = blob ? "blob" : "arrayBuffer";
          } else {
            method = "text";
          }
        } else {
          method = "text";
        }
      }
      return r[method]().then((body) => ({ r, body }));
    }
    return new Promise((resolve, reject) => {
      let timeoutHandler;
      if (timeout > 0) {
        timeoutHandler = setTimeout(() => {
          timeoutHandler = void 0;
          promise.abort();
          reject(new Error(`fetch ${url} timeout for ${timeout}ms.`));
        }, timeout);
      }
      const promise = fetch(url, init);
      promise.then((r) => {
        if (timeoutHandler)
          clearTimeout(timeoutHandler);
        return customParser ? customParser(r, defaultParser) : defaultParser(r);
      }).then(({ r, body }) => {
        if (!r.ok) {
          reject(new ResponseError(r, body));
          return;
        }
        resolve(body);
      }).catch(reject);
    });
  };
};

// src/index.ts
var fetchEx = fetch_default((url, init) => {
  const abortController = new AbortController();
  const promise = import("node-fetch").then(
    (it) => it.default(url, { ...init, signal: abortController.signal })
  );
  promise.abort = () => abortController.abort();
  return promise;
});
var src_default = fetchEx;
export {
  ResponseError,
  src_default as default,
  enableHTTPMethodOveride,
  fetchEx as fetch
};
