import destr from 'destr'; import { withBase, withQuery } from 'ufo'; class FetchError extends Error { constructor() { super(...arguments); this.name = "FetchError"; } } function createFetchError(request, error, response) { let message = ""; if (request && response) { message = `${response.status} ${response.statusText} (${request.toString()})`; } if (error) { message = `${error.message} (${message})`; } const fetchError = new FetchError(message); Object.defineProperty(fetchError, "request", { get() { return request; } }); Object.defineProperty(fetchError, "response", { get() { return response; } }); Object.defineProperty(fetchError, "data", { get() { return response && response._data; } }); return fetchError; } const payloadMethods = new Set(Object.freeze(["PATCH", "POST", "PUT", "DELETE"])); function isPayloadMethod(method = "GET") { return payloadMethods.has(method.toUpperCase()); } function isJSONSerializable(val) { if (val === void 0) { return false; } const t = typeof val; if (t === "string" || t === "number" || t === "boolean" || t === null) { return true; } if (t !== "object") { return false; } if (Array.isArray(val)) { return true; } return val.constructor && val.constructor.name === "Object" || typeof val.toJSON === "function"; } const textTypes = /* @__PURE__ */ new Set([ "image/svg", "application/xml", "application/xhtml", "application/html" ]); const JSON_RE = /^application\/(?:[\w!#$%&*`\-.^~]*\+)?json(;.+)?$/i; function detectResponseType(_contentType = "") { if (!_contentType) { return "json"; } const contentType = _contentType.split(";").shift(); if (JSON_RE.test(contentType)) { return "json"; } if (textTypes.has(contentType) || contentType.startsWith("text/")) { return "text"; } return "blob"; } const retryStatusCodes = /* @__PURE__ */ new Set([ 408, 409, 425, 429, 500, 502, 503, 504 ]); function createFetch(globalOptions) { const { fetch, Headers } = globalOptions; function onError(ctx) { if (ctx.options.retry !== false) { const retries = typeof ctx.options.retry === "number" ? ctx.options.retry : isPayloadMethod(ctx.options.method) ? 0 : 1; const responseCode = ctx.response && ctx.response.status || 500; if (retries > 0 && retryStatusCodes.has(responseCode)) { return $fetchRaw(ctx.request, { ...ctx.options, retry: retries - 1 }); } } const err = createFetchError(ctx.request, ctx.error, ctx.response); if (Error.captureStackTrace) { Error.captureStackTrace(err, $fetchRaw); } throw err; } const $fetchRaw = async function $fetchRaw2(_request, _opts = {}) { const ctx = { request: _request, options: { ...globalOptions.defaults, ..._opts }, response: void 0, error: void 0 }; if (ctx.options.onRequest) { await ctx.options.onRequest(ctx); } if (typeof ctx.request === "string") { if (ctx.options.baseURL) { ctx.request = withBase(ctx.request, ctx.options.baseURL); } if (ctx.options.params) { ctx.request = withQuery(ctx.request, ctx.options.params); } if (ctx.options.body && isPayloadMethod(ctx.options.method)) { if (isJSONSerializable(ctx.options.body)) { ctx.options.body = typeof ctx.options.body === "string" ? ctx.options.body : JSON.stringify(ctx.options.body); ctx.options.headers = new Headers(ctx.options.headers); if (!ctx.options.headers.has("content-type")) { ctx.options.headers.set("content-type", "application/json"); } if (!ctx.options.headers.has("accept")) { ctx.options.headers.set("accept", "application/json"); } } } } ctx.response = await fetch(ctx.request, ctx.options).catch(async (error) => { ctx.error = error; if (ctx.options.onRequestError) { await ctx.options.onRequestError(ctx); } return onError(ctx); }); const responseType = (ctx.options.parseResponse ? "json" : ctx.options.responseType) || detectResponseType(ctx.response.headers.get("content-type") || ""); if (responseType === "json") { const data = await ctx.response.text(); const parseFn = ctx.options.parseResponse || destr; ctx.response._data = parseFn(data); } else { ctx.response._data = await ctx.response[responseType](); } if (ctx.options.onResponse) { await ctx.options.onResponse(ctx); } if (!ctx.response.ok) { if (ctx.options.onResponseError) { await ctx.options.onResponseError(ctx); } } return ctx.response.ok ? ctx.response : onError(ctx); }; const $fetch = function $fetch2(request, opts) { return $fetchRaw(request, opts).then((r) => r._data); }; $fetch.raw = $fetchRaw; $fetch.create = (defaultOptions = {}) => createFetch({ ...globalOptions, defaults: { ...globalOptions.defaults, ...defaultOptions } }); return $fetch; } export { FetchError as F, createFetchError as a, createFetch as c };